package org.pluslibs.framework.swingplus.jpanel;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.pluslibs.framework.swingplus.utils.JPanelUtils;

public class JPanelGrid extends JPanel {

    private static final long serialVersionUID = 3682980862092839742L;

    protected static final int SINGLE_COL_WIDTH = 1;
    private static final Insets DEFAULT_INSETS = new Insets(0, 0, 0, 0);

    static final int DEFULT_EMPTY_VERTICAL_HEIGHT = 10;

    protected Map<Integer, ArrayList<Component>> compGrid = new LinkedHashMap<Integer, ArrayList<Component>>();
    protected Insets insets;
    private final JPanel contentPane;

    private final JScrollPane scrollPane;

    public JPanelGrid() {
        this(DEFAULT_INSETS);
    }

    public JPanelGrid(Insets insets) {
        setLayoutLeft();
        contentPane = new JPanelPlus();
        GridBagConstraints contraints = new GridBagConstraints();
        contraints.fill = GridBagConstraints.HORIZONTAL;
        contraints.anchor = GridBagConstraints.EAST;
        contraints.insets = DEFAULT_INSETS;
        scrollPane = new JScrollPane(contentPane);
        scrollPane.setBorder(null);
        add(scrollPane, contraints);
        contentPane.setLayout(new GridBagLayout());
        this.insets = insets;
    }

    @Override
    public void setSize(Dimension d) {
        super.setSize(d);
        // contentPane.setSize(d);
        // scrollPane.setSize(d);
    }

    protected void addField(Component component, int col, int gridwidth, Insets insets, boolean incrementRowCount) {
        ArrayList<Component> rowList;
        int row = compGrid.size();

        if (incrementRowCount) {
            ++row;
            rowList = new ArrayList<Component>();
            rowList.add(component);
            compGrid.put(row, rowList);
        } else {
            compGrid.get(row).add(component);
        }
        GridBagConstraints contraints = createConstraints(col, row, gridwidth, insets);
        contentPane.add(component, contraints);
    }

    private GridBagConstraints createConstraints(int col, int row, int gridwidth, Insets insets) {
        GridBagConstraints contraints = new GridBagConstraints();
        contraints.fill = GridBagConstraints.HORIZONTAL;
        contraints.anchor = GridBagConstraints.NORTHEAST;
        contraints.gridx = col;
        contraints.gridy = row;
        contraints.gridwidth = gridwidth;
        contraints.insets = insets;
        return contraints;
    }

    public void addRow(Component... components) {
        int col = 0;
        boolean incrementRowCount = true;
        for (Component component : components) {
            addField(component, col++, SINGLE_COL_WIDTH, insets, incrementRowCount);
            incrementRowCount = false;
        }
    }

    public void addNewLine() {
        addNewLine(DEFULT_EMPTY_VERTICAL_HEIGHT);
    }

    public void addNewLine(int height) {
        addField(JPanelUtils.createEmptyVertical(height), 0, SINGLE_COL_WIDTH, insets, true);
    }

    public int getColumnCount() {
        return getColumnCount(0);
    }

    private int getColumnCount(int row) {
        GridBagLayout layout = (GridBagLayout) contentPane.getLayout();
        int[][] layoutDimensions = layout.getLayoutDimensions();
        return layoutDimensions[1].length;
    }

    @Override
    public void setEnabled(boolean enabled) {
        for (Component component : contentPane.getComponents()) {
            component.setEnabled(enabled);
        }
        contentPane.setEnabled(enabled);
        super.setEnabled(enabled);
    }

    public void setComponentEnabled(boolean enabled, int col, int row) {
        compGrid.get(row).get(col).setEnabled(enabled);
    }

    public boolean isComponentEnabled(int col, int row) {
        return compGrid.get(row).get(col).isEnabled();
    }

    public void setComponentRowEnabled(boolean enabled, int row) {
        ArrayList<Component> compontens = compGrid.get(row);
        for (Component component : compontens) {
            component.setEnabled(enabled);
        }
    }

    public boolean isComponentRowEnabled(int row) {
        ArrayList<Component> compontens = compGrid.get(row);
        for (Component component : compontens) {
            if (component.isEnabled() == false) {
                return false;
            }
        }
        return true;
    }

    public void setLayoutCentered() {
        super.setLayout(new FlowLayout(FlowLayout.CENTER));
    }

    public void setLayoutLeft() {
        super.setLayout(new FlowLayout(FlowLayout.LEFT));
    }

    public int getRowCount() {
        return compGrid.size();
    }

    public void setComponentRowVisible(boolean visible, int row) {
        for (Component component : compGrid.get(row)) {
            component.setVisible(visible);
        }

    }
}
